<?php
require_once ROOT_PATH.'boot/req_inc.php';
require_once ROOT_PATH.'lib/ctl/Widget.class.php';
class DBWidgetAddFilter implements IRequestFilter{
	private $table='widget_opt';
	public  $request_is_json=true;
	private function get_data(RequestContext $context,$action,$key){
		if(isset($context->cache))	$result=$context->cache->get($key);
		if($result===NULL){
			try{
				$row = $context->db->create_mapper('system_config')
					->select('value')
					->where(array('code'=>'shop_template_'.$context->app_name))
					->find_by();
				if(empty($row)){
					$row = $context->db->create_mapper('system_config')
						->select('value')
						->where(array('code'=>'shop_template'))
						->find_by();
				}
				$request = $context->request;
				if(isset($request['profile'])) {
					@file_put_contents(ROOT_PATH . $context->app_name . DS.'views'. DS . 'view_template.log', $request['profile']);
					$context->set_session('current_template', $request['profile'], true); //主要是区别  后台预览 还是前台浏览
					$context->theme = $request['profile'];
				} else {
					if(!empty($row)) {
							$context->theme = $row['value'] ? $row['value'] :'default';
					}
				}
				if(strpos($action, '/') === 0) $action = substr($action ,1);
				$wgt_opt=$context->db->create_mapper($this->table);
				$wgt_opt->cols('widget_id,widget_action,border,title,request,mdtime')
					//->where_col('app_action',$action)
					->where("app_action = '{$action}' OR app_action = 'common'")
					->where(array('template'=>$context->theme))
					->where_col('state',0,'>');
		  		$result=@$wgt_opt->find_all_by();
		  		if(isset($context->cache)){
		  			if(! $result) $result='NULL';
		  			$context->cache->set($key,$result);
		  		}

			}catch(Exception $e){
				$context->log_error('DBWidgetAddFilter db error:'.$e->getMessage());
				$result=NULL;
			}
		}
		if($result==='NULL') $result=NULL;
		return 	$result;
	}
	function handle_before(array & $request,array & $response,array & $app){
		$context=$GLOBALS['context'];
		$key=$this->table.'/opt_'.str_replace(array('/','\\'),'_',$context->action);
		$options=$this->get_data($context,$context->action,$key);
		$time_offset=date_create ()->getOffset();
		Widget::$opt_mdtime=0;
		//添加widgets到缓存
		if($options && count($options)>0) {
			foreach ($options as $opt){
				$imdtime=strtotime($opt['mdtime'])+$time_offset+60;	//mysql date time settings:datetime_format=>%Y-%m-%d %H:%i:%s time_zone=>UTC
				if($imdtime>Widget::$opt_mdtime) Widget::$opt_mdtime=$imdtime;
				if($this->request_is_json) {
					$setting=json_decode($opt['request'],true);
				}else {
					$setting=eval("return {$opt['request']};");
				}
				Widget::add($opt['widget_id'],$opt['widget_action'],$opt['border'],$opt['title'],$setting);
			}
		}
	}
}


class CacheWidgetCallFilter implements IReponseFilter{
	public  $force=false;
	private $app_list=array();
	function handle_after(array & $request,array & $response,array & $app){
		$context=$GLOBALS['context'];
		$cache_dir=ROOT_PATH . $context->app_name .DS.'cache'.DS.'app'.DS;
		if(count(Widget::$wgt_list)<=0){
			$cache_file=$cache_dir.$context->action.'.wgt.php';
			if(file_exists($cache_file)){
				unlink($cache_file);
				Widget::$opt_mdtime=time();
			}

			return;
		}
		$path=dirname($context->action);
		if(DS=='\\') $path=str_replace('/',DS,$path);
		$path=$cache_dir.$path;
		if(! file_exists($path)) mkdir($path,0777,true);
		$path .=DS. basename($context->action).'.wgt';

		$cache_file =$path.'.php';
		$cache_dep  =$path.'.dep';
		if(! $this->force && $this->check_cache_valid($cache_file,$cache_dep)){
			self::call($cache_file);
			return ;
		}
		if(file_exists($cache_file)) unlink($cache_file);
		foreach($this->app_list as $app_file)
			file_put_contents($cache_file, trim(file_get_contents($app_file)),FILE_APPEND );
		file_put_contents($cache_dep,implode(';',$this->app_list));
		Widget::$opt_mdtime=filemtime($cache_file);
		self::call($cache_file);
	}
	private function call($cache_file){
		include_once  $cache_file;
		foreach(array_keys(Widget::$wgt_list) as $widget_id){
			Widget::call($widget_id,false);
		}
	}
	private function check_cache_valid($cache_file,$cache_dep){
		$result=true;
		if(file_exists($cache_file)) $cache_time=filemtime($cache_file);
		else{
			$result=false;
			$cache_time=-100;
		}
		if(Widget::$opt_mdtime>$cache_time) $result=false;

		foreach(Widget::$wgt_list as $widget_id=>$wgt){
			$action=$wgt['action'];
			$app_file=Widget::get_app_file($action);
			if(! file_exists($app_file)) continue;
			if($result){
				$im=filemtime($app_file);
				if($im && $im >=$cache_time) $result=false;
			}
			$this->app_list[]=$app_file;
		}
		$this->app_list=array_unique($this->app_list);
		if($result){
			if(file_exists($cache_dep)){
				$list=explode(';',file_get_contents($cache_dep));
				if((count($this->app_list)!=count($list) || array_diff($this->app_list,$list)))	$result=false;
			}else  $result=false;
		}
		return $result;
	}
}

class WidgetCallFilter implements IReponseFilter{
	function handle_after(array & $request,array & $response,array & $app){
		if(count(Widget::$wgt_list)<=0) return;
		foreach(array_keys(Widget::$wgt_list) as $widget_id){
			Widget::call($widget_id);
		}
	}
}